#include "NavigationEdgeList.h"

NavigationEdgeList::NavigationEdgeList()
{
	head = NULL;
	vertices = new VertexList();
}
NavigationEdgeList::NavigationEdgeList(NavigationEdge * headNavigationEdge)
{
	head = NULL;
	vertices = new VertexList();
	Add(headNavigationEdge);
}
NavigationEdgeList::~NavigationEdgeList()
{
	printf("deleting navigation edge list\n");
	List<NavigationEdge> * search = head;
	while(search)
	{
		search = search->Remove();
	}
	head = NULL;
	
	if(vertices)
	{
		delete(vertices);
		vertices = NULL;
	}
	printf("done deleting navigation edges\n");
}
List<NavigationEdge> * NavigationEdgeList::Add(NavigationEdge * payload)
{
	head = new List<NavigationEdge>(payload, head);
	if(!vertices->Contains(payload->GetRightEndpoint()))
		vertices->Add(payload->GetRightEndpoint());
	if(!vertices->Contains(payload->GetLeftEndpoint()))
		vertices->Add(payload->GetLeftEndpoint());
	return head;
}
void NavigationEdgeList::Remove(NavigationEdge * point)
{
	printf("NavigationEdgeList::Remove\n");
	List<NavigationEdge> * search = head;
	while(search)
	{
		printf("in while\n");
		if(search->payload && (search->payload == point))
		{
			if(search == head)
			{
				head = search->next;
			}
			printf("getting endpoints\n");
			Vertex * right = search->payload->GetRightEndpoint();
			Vertex * left = search->payload->GetLeftEndpoint();
			search = search->RemoveList();
			printf("checking vertex use\n");
			if(!VertexInUse(right))
			{
				printf("removing right vertex\n");
				vertices->Remove(right);
			}
			if(!VertexInUse(left))
			{
				printf("removing left vertex\n");
				vertices->Remove(left);
			}
			printf("done\n");
			break;
		}
		
		search = search->next;
	}		
	printf("Done NavigationEdgeList::Remove\n");
}
char * NavigationEdgeList::GetTags()
{
	List<NavigationEdge> * search = head;
	
	int length = 0;
	char * tag = NULL;
	
	while(search)
	{
		if(search->payload)
		{
			char * point = search->payload->GetTag();
			int commaSpace = 0;
			if(search->next)
				commaSpace = 1;
			tag = (char *)realloc(tag, (length + strlen(point) + 1 + commaSpace) * sizeof(char));
			memcpy(tag+length,point, strlen(point)+1);
	
			if(commaSpace)
			{
				int len = strlen(tag);
				tag[len] = ',';
				tag[len+1]='\0';
			}
			length += strlen(point)+commaSpace;
			delete point;
		}
		search = search->next;
	}
	return tag;
}
int NavigationEdgeList::GetLength()
{
	List<NavigationEdge> * search = head;
	int i =0;
	while(search)
	{
		i++;
		search = search->next;
	}
	return i;
}
NavigationEdge * NavigationEdgeList::VertexInUse(Vertex * vertex)
{
	List<NavigationEdge> * search = head;
	while(search)
	{
		if(search->payload && (search->payload->GetRightEndpoint() == vertex || 
							   search->payload->GetLeftEndpoint() == vertex))
		{
			return search->payload;
		}
		search = search->next;	
	}
	return NULL;
}
void NavigationEdgeList::ConnectEdge(NavigationEdge * edge)
{
	List<NavigationEdge> * search = head;
	int i = 0;
	int connected = 0;
	while(search)
	{
		if(search->payload)
		{
			#define CLOSE_DISTANCE 0.01
			if((edge->GetRightEndpoint()->GetPosition() | search->payload->GetRightEndpoint()->GetPosition()) < CLOSE_DISTANCE)
			{
				connected++;
				printf("right to right connection (%f,%f)\n", edge->GetLeftEndpoint()->GetPosition().x,edge->GetLeftEndpoint()->GetPosition().y);
				edge->AddRightEdge(search->payload->GetRightEndpoint());
				//search->payload->AddRightEdge(edge);
			}
			else if((edge->GetRightEndpoint()->GetPosition() | search->payload->GetLeftEndpoint()->GetPosition()) < CLOSE_DISTANCE)
			{
				connected++;
				printf("right to left connection (%f,%f)\n", edge->GetLeftEndpoint()->GetPosition().x,edge->GetLeftEndpoint()->GetPosition().y);
				edge->AddRightEdge(search->payload->GetLeftEndpoint());
				//search->payload->AddLeftEdge(edge);
			}
			else if((edge->GetLeftEndpoint()->GetPosition() | search->payload->GetLeftEndpoint()->GetPosition()) < CLOSE_DISTANCE)
			{
				connected++;
				printf("left to left connection (%f,%f)\n", edge->GetLeftEndpoint()->GetPosition().x,edge->GetLeftEndpoint()->GetPosition().y);
				edge->AddLeftEdge(search->payload->GetLeftEndpoint());
				//search->payload->AddLeftEdge(edge);
			}
			else if((edge->GetLeftEndpoint()->GetPosition() | search->payload->GetRightEndpoint()->GetPosition()) < CLOSE_DISTANCE)
			{
				connected++;
				printf("1 left to right connection (%f,%f)\n", edge->GetLeftEndpoint()->GetPosition().x,edge->GetLeftEndpoint()->GetPosition().y);
				edge->AddLeftEdge(search->payload->GetRightEndpoint());
				printf("2 left to right connection (%f,%f)\n", edge->GetLeftEndpoint()->GetPosition().x,edge->GetLeftEndpoint()->GetPosition().y);
				//search->payload->AddRightEdge(edge);
			}
		}
		i++;
		search = search->next;
	}	
	if(connected>1)
		printf("Connected 2 or more\n");
	Add(edge);
}
void NavigationEdgeList::SetParent(CharacterObject * parent)
{
	List<NavigationEdge> * search = head;
	while(search)
	{
		if(search->payload)
			search->payload->SetParent(parent);
		search = search->next;
	}
}

